from contextlib import asynccontextmanager
import io
from fastapi import Depends, FastAPI, File, Form, UploadFile, APIRouter, Request, HTTPException
import pandas as pd
from app.models.db import User, create_db_and_tables, engine
from fastapi import Depends
from sqlalchemy.ext.asyncio import AsyncSession, create_async_engine
from sqlalchemy.orm import sessionmaker
from app.schemas.schemas import UserCreate, UserRead, UserUpdate
from app.models.user import auth_backend, current_active_user, fastapi_users
from app.ai.ai_getdata import AIGetData
from app.api.clientapi import router as seesion_router
from app.api.sysbase import router as sysbase_router
from app.api.datasource import router as datasource_router
from app.api.dataset import router as dataset_router
from app.api.metadata import router as metadata_router
from app.api.role_dataset import router as role_dataset_router
from app.utils.auth import AutoPermissionMiddleware
from app.api.auth import router as custom_auth_router
from fastapi.middleware.cors import CORSMiddleware
from app.utils.rate_limiter import RateLimitMiddleware, limiter
from app.utils.request_middleware import RequestMiddleware
from app.utils.error_handler import setup_error_handlers
from app.utils.log_config import setup_logging
from config import ORIGINS
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
import os
import re

@asynccontextmanager
async def lifespan(app: FastAPI):
    # 应用启动时执行
    await create_db_and_tables()
    yield
    # 应用关闭时执行清理操作

app = FastAPI(
    title="数据分析平台API",
    description="提供数据分析和处理服务的API接口",
    version="1.0.0",
    lifespan=lifespan
)

# 设置日志配置 
setup_logging()

# 设置全局错误处理
setup_error_handlers(app)

# 添加自动权限检查中间件
app.add_middleware(AutoPermissionMiddleware)

# 添加请求中间件 - 最先添加，确保每个请求都有请求ID
app.add_middleware(RequestMiddleware)


# 添加速率限制中间件
# app.add_middleware(RateLimitMiddleware)

# 配置速率限制
# limiter.default_limit = 20  # 修改默认请求数
# limiter.default_window = 60  # 修改默认时间窗口（秒）
# limiter.set_endpoint_limit("upload_file", max_requests=3, window=60)
# limiter.set_endpoint_limit("send_msg", max_requests=10, window=60)
# limiter.set_endpoint_limit("get_report", max_requests=5, window=60)
# limiter.exempt_paths.add("/dk/api/public/health")  # 更新路径前缀
# limiter.exempt_paths.add("/dk/sessions/analysis_status")  # 更新路径前缀

# limiter.exempt_paths.add("/docs")
# limiter.exempt_paths.add("/redoc")
# limiter.exempt_paths.add("/login")

# 添加CORS中间件
app.add_middleware(
    CORSMiddleware,
    allow_origins=ORIGINS,
    allow_credentials=True,
    allow_methods=["*"],  # 允许所有方法
    allow_headers=["*"],
)


# 创建带有前缀的根路由器
root_router = APIRouter(prefix="/dk")

# 将所有路由器添加到根路由器中
# 注册认证路由 - 使用标准JWT登录
root_router.include_router(
    fastapi_users.get_auth_router(auth_backend, requires_verification=False), 
    prefix="/auth/jwt", 
    tags=["auth"],
)

# 添加自定义认证路由 - 包含我们定制的登录接口
# 注意：确保自定义路由优先级高于标准路由，以便优先处理登录请求
if custom_auth_router:
    root_router.include_router(custom_auth_router)

# 注册其他认证相关路由
root_router.include_router(
    fastapi_users.get_register_router(UserRead, UserCreate),
    prefix="/auth",
    tags=["auth"],
)
root_router.include_router(
    fastapi_users.get_reset_password_router(),
    prefix="/auth",
    tags=["auth"],
)
root_router.include_router(
    fastapi_users.get_users_router(UserRead, UserUpdate),
    prefix="/users",
    tags=["users"],
)

# 注册业务路由
root_router.include_router(seesion_router)
root_router.include_router(sysbase_router)
# 注册数据源和数据集管理路由
root_router.include_router(datasource_router)
root_router.include_router(dataset_router)
# 注册元数据服务路由
root_router.include_router(metadata_router)
# 注册示例路由
root_router.include_router(role_dataset_router)

# 注册知识库管理路由
from app.api.knowledge import router as knowledge_router
root_router.include_router(knowledge_router)

# 注册智能助手路由
from app.api.intelligent_assistant import router as intelligent_assistant_router
root_router.include_router(intelligent_assistant_router)

# 注册任务管理路由
from app.api.task_api import router as task_router
root_router.include_router(task_router)

# 将根路由器添加到应用中
app.include_router(root_router)

# 设置静态文件目录
static_dir = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "static")

# 挂载静态文件目录
app.mount("/static", StaticFiles(directory=static_dir), name="static")

# 自定义路由处理器，处理SPA前端路由
@app.get("/{full_path:path}")
async def serve_spa(request: Request, full_path: str):
    # 如果请求路径以/dk/开头，交给API处理
    if request.url.path.startswith("/dk/"):
        raise HTTPException(status_code=404, detail="API route not found")
    
    # 检查是否直接请求静态资源文件
    static_file_path = os.path.join(static_dir, full_path)
    
    # 如果是静态资源文件（CSS、JS、图片等），直接返回文件
    if os.path.exists(static_file_path) and os.path.isfile(static_file_path):
        # 检查文件扩展名
        if re.search(r"\.(js|css|png|jpg|jpeg|gif|svg|ico|woff|woff2|ttf|eot|html)$", full_path):
            return FileResponse(static_file_path)
    
    # 对于所有其他请求（包括前端路由如/chatV2/dataset），返回index.html
    index_html_path = os.path.join(static_dir, "index.html")
    if os.path.exists(index_html_path):
        return FileResponse(index_html_path)
    
    # 如果index.html不存在，返回404
    raise HTTPException(status_code=404, detail="Resource not found")

# 创建异步会话
async_session = sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
